package com.moss.cloud.common.file.realize;

import com.moss.cloud.common.file.exception.StorageErrorType;
import com.moss.cloud.common.file.model.StorageModel;
import com.moss.cloud.common.file.model.UploadRes;
import com.moss.cloud.common.file.operation.FileStorageOperation;
import com.moss.cloud.common.file.utils.*;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.RemoveObjectArgs;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.io.ByteArrayInputStream;
import java.io.InputStream;

/**
 * minio实现
 *
 * @author 瑾年
 * @date 2023年4月19日
 */
@Slf4j
public class MinioStorage implements FileStorageOperation {
    /**
     * 上传文件
     *
     * @param storageModel
     * @return
     */
    @Override
    @SneakyThrows
    public UploadRes upload(StorageModel storageModel) {
        String fileName = storageModel.getIsBase64() ? storageModel.getName() : storageModel.getMultipartFile().getOriginalFilename();
        FileDataPreUtil.isSizeAllowed(storageModel);
        FileDataPreUtil.isAllowed(fileName, storageModel.getStorageConfig().getSuffix());
        MinioClient minioClient = this.minioClient(storageModel);
        String bucketName = storageModel.getStorageConfig().getBucket();
        long size = 10485760L;
        if (storageModel.getStorageConfig().getSize() != null) {
            size = storageModel.getStorageConfig().getSize();
        }
        long actualSize = FileDataPreUtil.getSize(storageModel);
        String username = storageModel.getDirectory();
        String dir = FileDataPreUtil.genDirectory(storageModel.getDirectory());
        String renameFileName = UUIDUtil.rename(StringUtils.isNotBlank(fileName) ? fileName : "");
        String path = storageModel.getStorageConfig().getEchoUrl() + "/" + bucketName + "/" + dir + renameFileName;
        InputStream stream;
        if (storageModel.getInputStream() == null) {
            if (storageModel.getIsBase64()) {
                byte[] bytes = FileDataPreUtil.base64ToBytes(storageModel.getImgBase64());
                stream = new ByteArrayInputStream(bytes);
            } else {
                stream = storageModel.getMultipartFile().getInputStream();
            }
        } else {
            stream = storageModel.getInputStream();
        }
        minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object("/" + dir + renameFileName)
                .stream(stream, -1, size).build());
        return UploadResUtil.createUploadRes(path, renameFileName, storageModel.getStorageConfig().getType(), username, actualSize);
    }

    /**
     * 删除文件
     *
     * @param storageModel
     */
    @Override
    @SneakyThrows
    public void removeFile(StorageModel storageModel) {
        String bucketName = storageModel.getStorageConfig().getBucket();
        String objectName = storageModel.getFileId();
        MinioClient minioClient = this.minioClient(storageModel);
        minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(objectName).build());
    }

    /**
     * 生成客户端
     *
     * @param storageModel
     * @return
     */
    private MinioClient minioClient(StorageModel storageModel) {
        BooleanHandel.trueThrow(StringUtils.isBlank(storageModel.getStorageConfig().getAccessKey())).throwMessage(StorageErrorType.ACCESS_KEY_EMPTY);
        BooleanHandel.trueThrow(StringUtils.isBlank(storageModel.getStorageConfig().getSecretKey())).throwMessage(StorageErrorType.SECRET_KEY_EMPTY);
        BooleanHandel.trueThrow(StringUtils.isBlank(storageModel.getStorageConfig().getBaseUrl())).throwMessage(StorageErrorType.ENDPOINT_EMPTY);
        return MinioClient.builder().endpoint(storageModel.getStorageConfig().getBaseUrl())
                .credentials(storageModel.getStorageConfig().getAccessKey(), storageModel.getStorageConfig().getSecretKey()).build();
    }
}
